﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace ManageSystem.AuthorizationRequirement
{
    /// <summary>
    /// 权限处理的关键类
    /// </summary>
    public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
    {
        /// <summary>
        /// 通过IHttpContextAccessor可以获取HttpContext相关信息，但一定要注册服务
        /// </summary>
        private readonly IHttpContextAccessor accessor;

        /// <summary>
        /// 用于判断请求是否带有凭据和是否登录
        /// </summary>
        public IAuthenticationSchemeProvider Scheme { get; set; }

        /// <summary>
        ///  构造函数注入
        /// </summary>
        public PermissionHandler(IHttpContextAccessor accessor, IAuthenticationSchemeProvider scheme)
        {
            this.accessor = accessor;
            Scheme = scheme;
        }

        // 重写授权认证方法,每次jwt认证都会进入这个方法
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement permissionRequirement)
        {
            try
            {
                var httpContext = accessor.HttpContext;

                // 无权限
                if (!permissionRequirement.Permissions.Any())
                {
                    context.Fail();
                }

                // 判读请求是否拥有凭据，即是否登录
                var defaultAuthenticate = await Scheme.GetDefaultAuthenticateSchemeAsync();

                if (defaultAuthenticate == null)
                {
                    context.Fail();
                }
                var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);

                // 不为空代表登录成功,为空登录失败
                if (result?.Principal != null)
                {
                    // 获取生成Token时放在payload里的username
                    string username = accessor.HttpContext.User.FindFirst("username").Value;

                    // 当前请求url
                    string requestUrl = httpContext.Request.Path.Value.ToLower();
                    Console.WriteLine("--------------HandleRequirementAsync------------");
                    Console.WriteLine(requestUrl);

                    // 从权限表中查找当前用户是否有当前请求地址的权限
                    // var permission = permissionRequirement.Permissions.FirstOrDefault(a => a.url.ToLower() == requestUrl && a.username == username);
                    var permission = permissionRequirement.Permissions.FirstOrDefault(a => requestUrl.ToLower().Contains(a.url.ToLower()) && a.username == username);

                    if (permission == null)
                    {
                        context.Fail();
                    }
                    else
                    {
                        context.Succeed(permissionRequirement);
                    }
                }
                else
                {
                    context.Fail();
                }

                // 获取用户信息

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                context.Fail();
            }
        }

    }
}
